package phaseII;

import java.util.ArrayList;
import java.util.HashMap;

public class LL1Table 
{
	private int rows, cols;
	ArrayList<Token> tokens;
	ArrayList<Nonterminal> nonterminals;
	HashMap<String, ArrayList<Rule>>[][] table;
	
	public LL1Table(ArrayList<Token> t, ArrayList<Nonterminal> n, int numNT, int numT)
	{
		numT++;
		t.add(new Token("$"));
		
		cols = numT;
		rows = numNT;
		tokens = t;
		nonterminals = n;
		
		table = (HashMap<String, ArrayList<Rule>>[][]) new HashMap[cols][rows];
		
		for (int y = 0; y < cols; y++)
		{
			for (int z = 0; z < rows; z++)
			{
				table[y][z] = (new HashMap<String, ArrayList<Rule>>()); 
				table[y][z].put(nonterminals.get(z).toString()+","+tokens.get(y).toString(), new ArrayList<Rule>());
			}
		}
	}
	
	public void add(Nonterminal N, Token t, Rule R)
	{
		for (int x = 0; x < cols; x++)
		{
			for (int y = 0; y < rows; y++)
			{
				if (table[x][y].containsKey(N.toString()+","+t.toString()))
					table[x][y].get(N.toString()+","+t.toString()).add(R);
				
			}
		}
	}
	
	public HashMap<String, ArrayList<Rule>>[][] getTable()
	{
		return table;
	}
	
	public Rule getRule(Token t, Nonterminal N)
	{
		// watch out for index out of bounds, or nullpointerexceptions?
		
		return table[tokens.indexOf(t)][nonterminals.indexOf(N)].get(N+","+t).get(0);
	}
	
	public void print()
	{
		String nontermHeader,terminalHeader,rowRule;
        
        System.out.print(String.format("%1$-" + 1 + "s"," ") + "  ");
        for(int y=0;y<cols;y++)
        {
           terminalHeader =table[y][0].keySet().toString().substring(table[y][0].keySet().toString().indexOf(",")+1,table[y][0].keySet().toString().length()-1);
           System.out.print(String.format("%1$-" + 1 + "s",terminalHeader));

        }
        System.out.println();
        for(int x=0;x<rows;x++)
        {
            nontermHeader = table[0][x].keySet().toString().substring(1,table[0][x].keySet().toString().indexOf(","));
            System.out.print(String.format("%1$-" + 1 + "s",nontermHeader) + "  ");
            
            for(int y=0;y<cols;y++)
            {
                rowRule = table[y][x].get(table[y][x].keySet().toArray()[0]).toString();
                System.out.print(String.format("%1$-" + 1 + "s",rowRule));
                
            }
        }
	}
}
